package fina2.dcs.mail.owa;

import java.util.Arrays;
import java.util.Map;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;

import org.apache.log4j.Logger;

import fina2.dcs.mail.MailSenderBase;
import fina2.dcs.mail.manager.MailPropsKey;
import fina2.dcs.mail.manager.MailUser;
import fina2.dcs.mail.util.MailUtil;

@SuppressWarnings("serial")
public class MailSenderImplOWA implements MailSenderBase {
	private Logger log = Logger.getLogger(getClass());
	private MailUser mailUser;

	private String host;

	private Session session;

	private Transport transport;

	public MailSenderImplOWA(MailUser mailUser) {
		this.mailUser = mailUser;
		host = MailUtil.getProperty(MailPropsKey.MAIL_POP3_HOST, mailUser.getProperties());
		Properties prop = createExchangeMailProperties();
		Authenticator auth = new MailUtil.MyAuthenticator(mailUser.getUser(), mailUser.getPassword());
		session = Session.getDefaultInstance(prop, auth);
		try {
			transport = session.getTransport("smtp");
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
	}

	@Override
	public void send(String messageText, String subject, String[] cc, String[] bcc, String... toMailUser) throws Exception {
		try {
			MimeMessage message = new MimeMessage(session);
			message.setContent(messageText, "text/html; charset=UTF-8");
			message.setSubject(subject);
			message.setFrom(new InternetAddress(mailUser.getMailAddress()));

			InternetAddress[] addresses = new InternetAddress[toMailUser.length];
			for (int i = 0; i < addresses.length; i++) {
				addresses[i] = new InternetAddress(toMailUser[i]);
			}
			message.addRecipients(RecipientType.TO, addresses);
			message.saveChanges();

			transport.sendMessage(message, message.getAllRecipients());

			log.info("Send mail : " + Arrays.toString(toMailUser));
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage(), e);
		}
	}

	private Properties createExchangeMailProperties() {
		Map<String, String> sysProps = mailUser.getProperties();
		Properties props = new Properties();

		props.setProperty(MailPropsKey.EXJELLO_MAIL_UNFILTERED, sysProps.get(MailPropsKey.EXJELLO_MAIL_UNFILTERED));
		props.setProperty(MailPropsKey.EXJELLO_MAIL_LIMIT, sysProps.get(MailPropsKey.EXJELLO_MAIL_LIMIT));
		props.setProperty(MailPropsKey.EXJELLO_MAIL_DELETE, sysProps.get(MailPropsKey.EXJELLO_MAIL_DELETE));
		props.setProperty(MailPropsKey.MAIL_POP3_PORT, sysProps.get(MailPropsKey.MAIL_POP3_PORT));
		props.setProperty(MailPropsKey.MAIL_POP3_SSL_ENABLE, sysProps.get(MailPropsKey.MAIL_POP3_SSL_ENABLE));
		props.setProperty(MailPropsKey.MAIL_POP3_CONNECTION_TIMEUT, sysProps.get(MailPropsKey.MAIL_POP3_CONNECTION_TIMEUT));
		props.setProperty(MailPropsKey.MAIL_SMTP_CONNECTION_TIMEUT, sysProps.get(MailPropsKey.MAIL_SMTP_CONNECTION_TIMEUT));
		props.setProperty(MailPropsKey.MAIL_SMTP_SSL_ENABLE, sysProps.get(MailPropsKey.MAIL_SMTP_SSL_ENABLE));
		props.setProperty(MailPropsKey.MAIL_SMTP_PORT, sysProps.get(MailPropsKey.MAIL_SMTP_PORT));

		String mailBoox = sysProps.get(MailPropsKey.EXCHANGE_MAILBOX);

		props.put(MailPropsKey.EXCHANGE_MAILBOX, mailBoox);
		props.put("mail.pop3.from", mailBoox);
		props.put("mail.pop3.user", mailUser.getUser());
		props.put("mail.pop3.host", host);
		props.put("mail.smtp.from", mailBoox);
		props.put("mail.smtp.user", mailUser.getUser());
		props.put("mail.smtp.host", host);

		return props;
	}

	@Override
	public void connect() {
		try {
			transport.connect(host, mailUser.getUser(), mailUser.getPassword());
			log.info("Connected MailSender(SMTP).");
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
	}

	@Override
	public boolean isConected() {
		return transport.isConnected();
	}

	@Override
	public void close() {
		try {
			if (transport != null && transport.isConnected()) {
				transport.close();
				log.info("Close MailSender Connection (SMTP).");
			}
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
	}

}
